﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.Windows.Forms;

namespace GPCodeConjurer
{
	internal class GrabHandle
	{
		internal static int GrabHandleSize = 7;
		internal static int GlyphHandleSize = 5;


		public GrabHandle(Node node, HandleMoveBehavior moveBehavior)
		{
			this.Node = node;
			this.MoveBehavior = moveBehavior;
			this.Rect.Size = new Size(GrabHandleSize, GrabHandleSize);
		}

		public GrabHandle(Node node, HandleMoveBehavior moveBehavior, ContentAlignment alignment)
			: this(node, moveBehavior)
		{
			this.Alignment = alignment;
		}

		public GrabHandle(Node node, HandleMoveBehavior moveBehavior, ContentAlignment alignment, HandleShape handleShape)
			: this(node, moveBehavior, alignment)
		{
			this.HandleShape = handleShape;
		}

		public GrabHandle(Node node, HandleMoveBehavior moveBehavior, ContentAlignment alignment, HandleShape handleShape, Color fillColor)
			: this(node, moveBehavior, alignment, handleShape)
		{
			this.FillColor = fillColor;
		}



		public string Key = null;
		public Node Node = null;


		private Point location = Point.Empty;
		public Point Location
		{
			get
			{
				return location;
			}
			set
			{
				this.location = value;
				this.Rect.Location = new Point(this.location.X + this.alignmentOffset.Width, this.location.Y + this.alignmentOffset.Height);
			}
		}

		private Size alignmentOffset = Size.Empty;

		private ContentAlignment alignment = ContentAlignment.MiddleCenter;
		public ContentAlignment Alignment
		{
			get
			{
				return this.alignment;
			}
			set
			{
				this.alignment = value;

				Size offset = Size.Empty;
				int size = (this.HandleShape == HandleShape.Rectangle) ? GrabHandleSize : GlyphHandleSize;
				switch (this.alignment)
				{
					case ContentAlignment.BottomCenter:
						offset = new Size(-size / 2, -size);
						break;
					case ContentAlignment.BottomLeft:
						offset = new Size(0, -size);
						break;
					case ContentAlignment.BottomRight:
						offset = new Size(-size, -size);
						break;
					case ContentAlignment.MiddleCenter:
						offset = new Size(-size / 2, -size / 2);
						break;
					case ContentAlignment.MiddleLeft:
						offset = new Size(0, -size);
						break;
					case ContentAlignment.MiddleRight:
						offset = new Size(-size, -size);
						break;
					case ContentAlignment.TopCenter:
						offset = new Size(-size / 2, 0);
						break;
					case ContentAlignment.TopLeft:
						offset = new Size(0, 0);
						break;
					case ContentAlignment.TopRight:
						offset = new Size(-size, 0);
						break;
				}
				alignmentOffset = offset;
			}
		}

		public Rectangle Rect = Rectangle.Empty;
		public Cursor MouseOverCursor = null;
		public Color FillColor = Color.White;
		public HandleShape HandleShape = HandleShape.Rectangle;
		public HandleMoveBehavior MoveBehavior = HandleMoveBehavior.All;

		/*
		public void SetLocation(PointF point)
		{
			this.SetLocation(new Point(Convert.ToInt32(point.X), Convert.ToInt32(point.Y)));
		}

		public void SetLocation(float x, float y)
		{
			this.SetLocation(Convert.ToInt32(x), Convert.ToInt32(y));
		}

		public void SetLocation(Point point)
		{
			this.Location = point;
			this.Rect.Location = new Point(this.Location.X - GrabHandleSize / 2, this.Location.Y - GrabHandleSize / 2);
		}


		public void SetLocation(int x, int y)
		{
			this.Location = new Point(x, y);
			this.Rect.Location = new Point(this.Location.X - GrabHandleSize / 2, this.Location.Y - GrabHandleSize / 2);
		}
		*/

		internal void PaintGrabHandle(Graphics g)
		{
			if (this.HandleShape == HandleShape.Rectangle)
			{
				ControlPaint.DrawGrabHandle(g, this.Rect, true, true);
			}
			else if (this.HandleShape == HandleShape.Diamond)
			{
				using (GraphicsPath gp = new GraphicsPath())
				{
					gp.AddRectangle(new RectangleF(-GlyphHandleSize / 2, -GlyphHandleSize/2, GlyphHandleSize, GlyphHandleSize));
					gp.CloseFigure();

					var state = g.Save();
					var bounds = gp.GetBounds();
					g.TranslateTransform(this.Location.X, this.Location.Y);
					g.RotateTransform(45f);
					using (var glyphBrush = new SolidBrush(this.FillColor))
					{
						g.FillPath(glyphBrush, gp);
					}
					g.DrawPath(Pens.Black, gp);
					g.Restore(state);
				}
			}
		}


	}


	public enum HandleMoveBehavior
	{
		All,
		Horizontally,
		Vertically,
		NWSE,
		NESW,
		NodeCircular
	}


	public enum HandleShape
	{
		Rectangle,
		Diamond
	}





}
